﻿using DapperBaseDal.Expressions;
using DapperExtensions;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace DapperBaseDal
{
    public interface IBaseService<T> where T : class
    {
        IBaseRepository<T> CurrentRepository { get; }

        int Count(object predicate = null);
        int Count(Expression<Func<T, bool>> predicate);
        Task<int> CountAsync(object predicate = null);
        Task<int> CountAsync(Expression<Func<T, bool>> predicate);
        bool Delete(Expression<Func<T, bool>> predicate);
        bool Delete(object predicate);
        bool Delete(T entity);
        Task<bool> DeleteAsync(Expression<Func<T, bool>> predicate);
        Task<bool> DeleteAsync(object predicate);
        Task<bool> DeleteAsync(T entity);
        T Get(dynamic id);
        Task<T> GetAsync(dynamic id);
        T GetFirst(object predicate = null, object sort = null);
        T GetFirst(Expression<Func<T, bool>> predicate);
        T GetFirst(Expression<Func<T, bool>> predicate, IList<ISort> sort);
        T GetFirst(Expression<Func<T, bool>> predicate, object sort);
        T GetFirst(Expression<Func<T, bool>> predicate, SortDirection ascending, params Expression<Func<T, object>>[] sortingExpression);
        Task<T> GetFirstAsync(object predicate = null, object sort = null);
        Task<T> GetFirstAsync(Expression<Func<T, bool>> predicate);
        Task<T> GetFirstAsync(Expression<Func<T, bool>> predicate, IList<ISort> sort);
        Task<T> GetFirstAsync(Expression<Func<T, bool>> predicate, object sort);
        Task<T> GetFirstAsync(Expression<Func<T, bool>> predicate, SortDirection ascending, params Expression<Func<T, object>>[] sortingExpression);
        IEnumerable<T> GetList(object predicate = null, object sort = null);
        IEnumerable<T> GetList(Expression<Func<T, bool>> predicate, IList<ISort> sort = null);
        IEnumerable<T> GetList(Expression<Func<T, bool>> predicate, SortDirection ascending, params Expression<Func<T, object>>[] sortingExpression);
        IEnumerable<T> GetList(object predicate, IList<ISort> sort);
        Task<IEnumerable<T>> GetListAsync(object predicate = null, object sort = null);
        Task<IEnumerable<T>> GetListAsync(Expression<Func<T, bool>> predicate, IList<ISort> sort = null);
        Task<IEnumerable<T>> GetListAsync(Expression<Func<T, bool>> predicate, SortDirection ascending, params Expression<Func<T, object>>[] sortingExpression);
        Task<IEnumerable<T>> GetListAsync(object predicate, IList<ISort> sort);
        IEnumerable<T> GetPage(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> predicate, IList<ISort> sort);
        IEnumerable<T> GetPage(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> predicate, object sort);
        IEnumerable<T> GetPage(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> predicate, SortDirection ascending, params Expression<Func<T, object>>[] sortingExpression);
        IEnumerable<T> GetPage(int pageIndex, int pageSize, out int totalCount, object predicate, IList<ISort> sort);
        IEnumerable<T> GetPage(int pageIndex, int pageSize, out int totalCount, object predicate, object sort);
        Task<Tuple<IEnumerable<T>, int>> GetPageAsync(int pageIndex, int pageSize, Expression<Func<T, bool>> predicate, IList<ISort> sort);
        Task<Tuple<IEnumerable<T>, int>> GetPageAsync(int pageIndex, int pageSize, Expression<Func<T, bool>> predicate, object sort);
        Task<Tuple<IEnumerable<T>, int>> GetPageAsync(int pageIndex, int pageSize, Expression<Func<T, bool>> predicate, SortDirection ascending, params Expression<Func<T, object>>[] sortingExpression);
        Task<Tuple<IEnumerable<T>, int>> GetPageAsync(int pageIndex, int pageSize, object predicate, IList<ISort> sort);
        Task<Tuple<IEnumerable<T>, int>> GetPageAsync(int pageIndex, int pageSize, object predicate, object sort);
        IEnumerable<T> GetSet(int firstResult, int maxResults, Expression<Func<T, bool>> predicate, IList<ISort> sort);
        IEnumerable<T> GetSet(int firstResult, int maxResults, Expression<Func<T, bool>> predicate, object sort);
        IEnumerable<T> GetSet(int firstResult, int maxResults, Expression<Func<T, bool>> predicate, SortDirection ascending, params Expression<Func<T, object>>[] sortingExpression);
        IEnumerable<T> GetSet(int firstResult, int maxResults, object predicate, IList<ISort> sort);
        IEnumerable<T> GetSet(int firstResult, int maxResults, object predicate, object sort);
        Task<IEnumerable<T>> GetSetAsync(int firstResult, int maxResults, Expression<Func<T, bool>> predicate, IList<ISort> sort);
        Task<IEnumerable<T>> GetSetAsync(int firstResult, int maxResults, Expression<Func<T, bool>> predicate, object sort);
        Task<IEnumerable<T>> GetSetAsync(int firstResult, int maxResults, Expression<Func<T, bool>> predicate, SortDirection ascending, params Expression<Func<T, object>>[] sortingExpression);
        Task<IEnumerable<T>> GetSetAsync(int firstResult, int maxResults, object predicate, IList<ISort> sort);
        Task<IEnumerable<T>> GetSetAsync(int firstResult, int maxResults, object predicate, object sort);
        void Insert(IEnumerable<T> entities);
        dynamic Insert(T entity);
        Task InsertAsync(IEnumerable<T> entities);
        Task<dynamic> InsertAsync(T entity);
        IBaseRepository<T> SetRepository();
        bool Update(T entity, bool ignoreAllKeyProperties = false);
        Task<bool> UpdateAsync(T entity, bool ignoreAllKeyProperties = false);
    }
}